
import cv2
import logging
import time
import numpy as np
from DailyBase import *
from Log2File import *


logger = logging.getLogger(__name__)


PTYangBanRect = [538, 71, 680, 213]
PTSx = 156
PTSy = 77
PTSpace = 4
PBlockSize = 76


class PinTu(DailyBase):

    def __init__(self, enum):
        self.RCName = __name__
        self.LogHeader = self.RCName +str(enum.port)
        self.enum = enum
        self.started = False
        self.YouXiBi = -1
        self.PlayTimes = 0
        self.clicks = []
        self.loadPrivateActions(self.areaDict, PinTuActions)

        logger.info("{} has {} actions".format(self.LogHeader, len(self.areaDict)))

        for i in range(4):
            for j in range(4):
                sx = PTSx + (PBlockSize + PTSpace) * j + PBlockSize/2
                sy = PTSy + (PBlockSize + PTSpace) * i + PBlockSize/2
                self.clicks.append((int(sx) , int(sy), str(i*4+j)))

        #for i in range( len(self.clicks) ):
        #    logger.info("{}".format(self.clicks[i]))

    def KaiShi(self):
        Log2File.info(self.enum.port, "id {} kaishi !!!".format(self.RCName))
        self.PlayTimes = 0
        self.begin()


    def process_private(self, img = None, data = None):

        logger.info("{} data: {}".format(self.LogHeader, data))

        if self.PlayTimes > 10:
            self.enum.click(CloseYouLeChang)
            self.stop()
            return

        if self.areaDict['KaiShiPinTu'].detect(img, self.enum) < 10:

            if self.areaDict['YouXiBi'].detect(img) < 5:
                logger.info("没有游戏币了, quit!!!!")
                Log2File.info(self.enum.port, "id {} 没有游戏币了!!!".format(self.RCName))
                self.enum.click(CloseYouLeChang)
                self.stop()
                return

            self.enum.click(self.areaDict['KaiShiPinTu'].click)

        elif self.areaDict['ZhiHuiPinTu'].detect(img, self.enum) < 10:
            Log2File.info(self.enum.port, "id {} 开始拼图 {}".format(self.RCName, self.PlayTimes))
            self.ZhiHuiPinPin(self.enum, img)
            self.PlayTimes += 1









    def ZhiHuiPinPin(self, enum, img):

        yangbanImgList, pintuList = self.segmentation(img)

        match_result = self.PinPinWithAbsDiff(yangbanImgList, pintuList)

        #currSeq = [ k for k in range(16)]

        #self.drawCurrRes(currSeq, pintuList)

        self.KaiShiPin(enum, match_result, pintuList)




    def KaiShiPin(self, enum, match_result, pintuList):

        lenth = len(match_result)
        logger.info("match_result {}".format(match_result))
        for i in range(lenth ):

            for j in range(lenth):
                if i == match_result[j]:
                    self.poutSeq(match_result)
                    logger.info("{} {} {}  ".format(i, j, match_result[j]))
                    #self.drawCurrRes(pintuList, i, j, wname="bimg")

                    if enum is not None:
                        if i != j:
                            enum.click(self.clicks[i], delay = 100)
                            enum.click(self.clicks[j], delay = 100)

                    #cv2.waitKey()

                    t = match_result[i]
                    match_result[i] = match_result[j]
                    match_result[j] = t
                    p1 = pintuList[i]
                    pintuList[i] = pintuList[j]
                    pintuList[j] = p1
                    break

            self.poutSeq(match_result)
            #self.poutSeq(match_result)


            #self.drawCurrRes(pintuList,i,j)
            #self.drawMatchRes(match_result, pintuList)
            #cv2.waitKey()

    def drawCurrRes(self, pintuList, p0, p1, wname = "imgc"):

        logger.info("p0 {} p1 {}".format(p0, p1))
        size = PBlockSize * 4
        imgr = np.zeros((size,size,3), dtype=np.uint8)

        for j in range(4):
            for i in range(4):
                sx = i * PBlockSize
                sy = j * PBlockSize
                imgr[sy: sy + PBlockSize, sx:sx + PBlockSize] = pintuList[j * 4 + i]['image']



        sx = self.clicks[p0][0] - PTSx - 10
        sy = self.clicks[p0][1] - PTSy - 10

        logger.info("p0 {} {}".format(p0, self.clicks[p0]))
        cv2.circle(imgr, (sx, sy), 5, (0,0,255), -1)

        sx = self.clicks[p1][0] - PTSx + 10
        sy = self.clicks[p1][1] - PTSy + 10

        cv2.circle(imgr, (sx, sy), 5, (255,0,0), -1)

        cv2.imshow(wname,imgr)
        #cv2.waitKey()


    def poutSeq(self,match_result):
        pass
        #for k1 in range(4):
        #    logger.info("{:2} {:2} {:2} {:2} ".format(match_result[k1 * 4], match_result[k1 * 4 + 1], match_result[k1 * 4 + 2], match_result[k1 * 4 + 3]))


    def PinPinWithAbsDiff(self, yangbanImgList, pintuList):

        #缩小与样本一致
        pintuImgList = []
        for pintu in pintuList:
            img = cv2.resize(pintu['image'], (36,36))
            pintuImgList.append(img)
            #cv2.imshow("111", pintu['image'])
            # cv2.imshow("img0", img0 )
            #cv2.waitKey()


        result = []
        for i in range(len(pintuImgList)):
            best_match = 0
            min_score = 0x7fffffff
            img0 = pintuImgList[i]
            for j in range(len(yangbanImgList)):

                res = cv2.absdiff(img0, yangbanImgList[j]['image'])
                score = np.mean(res)
                #logger.info("{} {} {} score {}".format(self.name, i, j,score))
                if min_score > score:
                    min_score = score
                    best_match = j
            result.append(best_match)
            #logger.info("{} => {} best score: {}".format(i, best_match, min_score))
            #cv2.imshow("img0",img0)
            #cv2.imshow("match", yangbanImgList[best_match]['image'])
            #cv2.waitKey()

        return result

    def segmentation(self,img):
        logger.info("  ")

        yangban = img[PTYangBanRect[1]:PTYangBanRect[3], PTYangBanRect[0]:PTYangBanRect[2]]
        yangban = cv2.resize(yangban, (144,144))
        print(yangban.shape)
        size0 = yangban.shape[0]
        size = size0 / 4.0
        yangbanImgList = []
        for i in range(4):
            for j in range(4):
                sx = size * j
                sy = size * i
                area = [int(sx), int(sy), int(sx + size), int(sy + size)]
                #print(area)
                img0 = yangban[area[1]:area[3], area[0]:area[2]]
                yangbanImgList.append({'x': j, 'y': i, 'image': img0})
                #print(img0.shape)

        startx = PTSx
        starty = PTSy
        size = PBlockSize
        space = 4


        #cv2.imshow("img", img)
        pintuList = []
        for i in range(4):
            for j in range(4):
                sx = startx+(size + space)*j
                sy = starty+(size + space)*i
                area = [sx, sy, sx + size, sy + size]
                #print(area)
                img0 = img[area[1]:area[3], area[0]:area[2]]
                pintuList.append({'x': j, 'y': i, 'image': img0})


        return yangbanImgList,pintuList





    def drawMatchRes(self, result, pintuList):

        size = PBlockSize * 4
        imgr = np.zeros((size,size,3), dtype=np.uint8)
        print(result)
        for j in range(4):
            for i in range(4):
                sx = i * PBlockSize
                sy = j * PBlockSize
                kk = 0
                for k in range(16):
                    if result[k] == j * 4 + i:
                        kk = k
                        break
                imgr[sy: sy + PBlockSize, sx:sx + PBlockSize] = pintuList[kk]['image']
        cv2.imshow("imgM",imgr)
        #cv2.waitKey()
